/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       skill_set.cpp

	$Header:  $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "skill_set.h"

#include "bitset_io.h"
#include "enum_operations.h"
#include "skill_properties.h"

// ------------------------------------------------------------------------------
// Is the skill of the indicated type?
// ------------------------------------------------------------------------------
static bool is_skill_of_type(t_skill_type skill, bool primary, bool secondary, bool magic, bool secular)
{
	if (is_primary_skill(skill))
	{
		if (!primary)
			return false;
	}
	else
	{
		if (!secondary)
			return false;
	}

	if (is_magic_skill(skill))
	{
		if (!magic)
			return false;
	}
	else
	{
		if (!secular)
			return false;
	}

	return true;
}

#pragma warning( push )
#pragma warning( disable: 4800 ) // disable the "int -> bool" warning

// ------------------------------------------------------------------------------
// Get the set of skills for the given types of skills 
// ------------------------------------------------------------------------------
t_skill_set const & get_skill_set(bool primary, bool secondary, bool magic, bool secular)
{
	static t_skill_set k_skill_sets[2][2][2][2];
	bool initialized = false;

	if (!initialized)
	{
		int init_primary, init_secondary, init_magic, init_secular;
		t_skill_type skill;

		for (init_primary = 0; init_primary < 2; init_primary++)
		{
			for (init_secondary = 0; init_secondary < 2; init_secondary++)
			{
				for (init_magic = 0; init_magic < 2; init_magic++)
				{
					for (init_secular = 0; init_secular < 2; init_secular++)
					{
						for (skill = t_skill_type(0); skill < k_skill_count; enum_incr(skill))
						{
							k_skill_sets[init_primary][init_secondary][init_magic][init_secular][skill] = 
								is_skill_of_type(skill, init_primary, init_secondary, init_magic, init_secular);
						}
					}
				}
			}
		}

		initialized = true;
	}

	return k_skill_sets[primary][secondary][magic][secular];
}

#pragma warning( pop )

namespace
{
	const int k_version = 0;
}

// ------------------------------------------------------------
// read skill set
// ------------------------------------------------------------
bool t_skill_set::read_version( std::streambuf& stream, int version )
{
	if (version < 0 || version > k_version)
		return false;

	*this = get_bitset<k_skill_count>( stream );

	return true;
}

// ------------------------------------------------------------
// read skill set
// ------------------------------------------------------------
bool t_skill_set::read( std::streambuf& stream )
{
	t_uint8 version = get<t_uint8>(stream);

	return read_version( stream, version );
}

// ------------------------------------------------------------
// write skill set
// ------------------------------------------------------------
bool t_skill_set::write( std::streambuf& stream ) const
{
	put<t_uint8>( stream, k_version );
	put_bitset< k_skill_count >( stream, *this );
	return true;
}
